package com.katian.chep.palettes;

import com.katian.FileInfo;
import com.katian.FileMeta;
import com.katian.UploadFiles;
import com.katian.etat_compte.*;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Controller
@RequestMapping("/chep")
public class ChepPalettesController {
    public static final String COMMANDES = "commandes";
    public static final String CLIENTS = "clients";
    public static final String RESULT = "result";

    protected final Log logger = LogFactory.getLog(getClass());

    @RequestMapping(method = RequestMethod.GET)
    public String printWelcome(ModelMap model) {
        model.addAttribute(COMMANDES, getCommandesFileName());
        model.addAttribute(CLIENTS, getClientsFileName());
        model.addAttribute(RESULT, getResultFileName());
        return "chep";
    }

    @RequestMapping(value = "/get.commandes.file.name", method = RequestMethod.GET)
    @ResponseBody
    public FileInfo getCommandesFileName() {
        return getFileName(COMMANDES);
    }

    @RequestMapping(value = "/get.clients.file.name", method = RequestMethod.GET)
    @ResponseBody
    public FileInfo getClientsFileName() {
        return getFileName(CLIENTS);
    }

    @RequestMapping(value = "/get.result.file.name", method = RequestMethod.GET)
    @ResponseBody
    public FileInfo getResultFileName() {
        return getFileName(RESULT);
    }

    @RequestMapping(value = "/upload.commandes", method = RequestMethod.POST)
    @ResponseBody
    public List<FileMeta> uploadCommandes(@ModelAttribute(value = "FORM") UploadFiles files, BindingResult result) {
        return handleNewFile(files, result, COMMANDES);
    }

    @RequestMapping(value = "/upload.clients", method = RequestMethod.POST)
    @ResponseBody
    public List<FileMeta> uploadClients(@ModelAttribute(value = "FORM") UploadFiles files, BindingResult result) {
        return handleNewFile(files, result, CLIENTS);
    }

    @RequestMapping(value = "/get.result.file", method = RequestMethod.GET)
    public void getResultFile(HttpServletResponse response) throws IOException {
        FileInfo resultFileName = getResultFileName();
        if (resultFileName != null) {
            File resultFile = new File(getFilePath(RESULT) + File.separator + resultFileName.getFileName());
            if (resultFile.exists()) {
                response.setContentType("application-xdownload");
                response.setHeader("Content-Disposition", "attachment; filename=\"" + resultFile.getName() + "\"");

                FileInputStream fileInputStream = new FileInputStream(resultFile);
                IOUtils.copy(fileInputStream, response.getOutputStream());
                fileInputStream.close();
                response.flushBuffer();

            }
        }
    }

    @RequestMapping(value = "/generate", method = RequestMethod.GET)
    @ResponseBody
    public String generate() throws Exception {
        try {
            System.out.println("----------------------------------------------------");
            System.out.println("Début du processus de generation du fichier PALETTES-CHEP.xlsx");
            String folderPath = getFilePath(RESULT);
            File folder = new File(folderPath);
            if (folder.exists()) {
                FileUtils.cleanDirectory(folder);
            } else {
                FileUtils.forceMkdir(folder);
            }

            InputStream clientsInput = new FileInputStream(getFile(CLIENTS));
            Map<String, Client> clients = RapportUtilisationChepPalletUtil.getClient(clientsInput, ';');
            System.out.println("Nb clients: " + clients.size());

            InputStream commandesInput = new FileInputStream(getFile(COMMANDES));
            Map<Long, Commande> commandes = RapportUtilisationChepPalletUtil.getCommandes(commandesInput, ';');
            System.out.println("Nb commandes: " + commandes.size());

            System.out.println("Generation du fichier excel...");
            XSSFWorkbook wb = RapportUtilisationChepPalletUtil.generateRapportUtilisationChepPallet(commandes, clients);

            File file = new File(folder.getAbsolutePath() + File.separator + "PALETTES-CHEP.xlsx");

            System.out.println("Ecriture sur disque du fichier: " + file.getAbsolutePath());
            wb.write(new FileOutputStream(file));
        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        }


        return "cool";
    }

    private List<FileMeta> handleNewFile(UploadFiles files, BindingResult result, String folderName) {
        List<FileMeta> fileMetas = null;
        if (!result.hasErrors()) {
            try {
                String folderPath = getFilePath(folderName);
                File folder = new File(folderPath);
                if (folder.exists()) {
                     FileUtils.cleanDirectory(folder);
                } else {
                    FileUtils.forceMkdir(folder);
                }

                CommonsMultipartFile multipartFile = files.getFile();

                FileMeta fileMeta = new FileMeta();
                fileMeta.setFileName(multipartFile.getName());
                fileMeta.setFileType(multipartFile.getContentType());
                fileMeta.setFileSize(multipartFile.getSize() / 1024 + " Kb");
                if (fileMetas == null) {
                    fileMetas = new ArrayList<>();
                }
                fileMetas.add(fileMeta);

                String filePath = folderPath + File.separator + com.katian.FileUtils.getValidFileName(multipartFile.getOriginalFilename());

                File file = new File(filePath);
                multipartFile.getFileItem().write(file);
            } catch (Exception e) {
                logger.error("Can't save file", e);
            }
        }

        return fileMetas;
    }

    private String getFilePath(String fileName) {
        return System.getProperty("java.io.tmpdir") + File.separator + "chep" + File.separator + fileName;
    }

    private FileInfo getFileName(String folderName) {
        FileInfo info = new FileInfo();
        File file = getFile(folderName);
        if (file != null) {
            info.setFileName(file.getName());
        }
        return info;
    }

    private File getFile(String folderName) {
        File file = null;
        String folderPath = getFilePath(folderName);
        File folder = new File(folderPath);
        if (folder.exists()) {
            File[] files = folder.listFiles();
            if (files != null && files.length > 0) {
                file = files[0];
            }
        }
        return file;
    }
}